home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / edit / thesrc20.zip / comm1.c < prev    next >
C/C++ Source or Header  |  1995-01-26  |  71KB  |  2,211 lines

  1. /***********************************************************************/
  2. /* COMM1.C - Commands A-D                                              */
  3. /* This file contains all commands that can be assigned to function    */
  4. /* keys or typed on the command line.                                  */
  5. /***********************************************************************/
  6. /*
  7.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  8.  * Copyright (C) 1991-1995 Mark Hessling
  9.  *
  10.  * This program is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU General Public License as
  12.  * published by the Free Software Foundation; either version 2 of
  13.  * the License, or any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18.  * General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to:
  22.  *
  23.  *    The Free Software Foundation, Inc.
  24.  *    675 Mass Ave,
  25.  *    Cambridge, MA 02139 USA.
  26.  *
  27.  *
  28.  * If you make modifications to this software that you feel increases
  29.  * it usefulness for the rest of the community, please email the
  30.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  31.  * This software is going to be maintained and enhanced as deemed
  32.  * necessary by the community.
  33.  *
  34.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  35.  * 36 David Road                     Phone: +61 7 849 7731
  36.  * Holland Park                      Fax:   +61 7 875 5314
  37.  * QLD 4121
  38.  * Australia
  39.  */
  40.  
  41. /*
  42. $Id: comm1.c 2.0 1995/01/26 16:29:49 MH Release MH $
  43. */
  44.  
  45. #include <stdio.h>
  46.  
  47. #include "the.h"
  48. #include "proto.h"
  49.  
  50. /*#define DEBUG 1*/
  51.  
  52. /*man-start*********************************************************************
  53. COMMAND
  54.      add - add blank line
  55.  
  56. SYNTAX
  57.      Add [n]
  58.  
  59. DESCRIPTION
  60.      The ADD command inserts the specified number of blank lines after
  61.      the current_line (if issued from the command line) or after the
  62.      focus_line (if issued from the FILEAREA or PREFIX areas).
  63.      If SET NEWLINE is set to ALIGNED, the cursor is positioned in
  64.      the column corresponding to the first column not containing a 
  65.      space in the line above.
  66.      If SET NEWLINE is set to LEFT, the cursor is positioned in the
  67.      first column.
  68.  
  69. COMPATIBILITY
  70.      XEDIT: Compatible.
  71.      KEDIT: Compatible.
  72.  
  73. DEFAULT
  74.      1
  75.  
  76. SEE ALSO
  77.      SOS ADDLINE
  78.  
  79. STATUS
  80.      Complete
  81. **man-end**********************************************************************/
  82. #ifdef PROTO
  83. short Add(CHARTYPE *params)
  84. #else
  85. short Add(params)
  86. CHARTYPE *params;
  87. #endif
  88. /***********************************************************************/
  89. {
  90. /*-------------------------- external data ----------------------------*/
  91.  extern bool curses_started;
  92. /*--------------------------- local data ------------------------------*/
  93. #define ADD_PARAMS  1
  94.  CHARTYPE *word[ADD_PARAMS+1];
  95.  unsigned short num_params=0;
  96.  LINETYPE num_lines=0L;
  97. /*--------------------------- processing ------------------------------*/
  98. #ifdef TRACE
  99.  trace_function("comm1.c:   Add");
  100. #endif
  101. /*---------------------------------------------------------------------*/
  102. /* Validate the parameters that have been supplied. The one and only   */
  103. /* parameter should be a positive integer greater than zero.           */
  104. /* If no parameter is supplied, 1 is assumed.                          */
  105. /*---------------------------------------------------------------------*/
  106.  num_params = param_split(params,word,ADD_PARAMS,WORD_DELIMS,TEMP_PARAM);
  107.  if (num_params == 0)
  108.     {
  109.      num_params = 1;
  110.      word[0] = (CHARTYPE *)"1";
  111.     }
  112.  if (num_params != 1)
  113.     {
  114.      display_error(1,word[1],FALSE);
  115. #ifdef TRACE
  116.      trace_return();
  117. #endif
  118.      return(RC_INVALID_OPERAND);
  119.     }
  120.  if (!valid_positive_integer(word[0]))
  121.     {
  122.      display_error(4,word[0],FALSE);
  123. #ifdef TRACE
  124.      trace_return();
  125. #endif
  126.      return(RC_INVALID_OPERAND);
  127.     }
  128.  num_lines = atol(word[0]);
  129.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  130.  insert_new_line((CHARTYPE *)"",0,num_lines,get_true_line(),FALSE,FALSE,CURRENT_VIEW->display_low);
  131.  if (curses_started
  132.  && CURRENT_VIEW->current_window == WINDOW_COMMAND)
  133.     cursor_home(TRUE);
  134. #ifdef TRACE
  135.  trace_return();
  136. #endif
  137.  return(RC_OK);
  138. }
  139. /*man-start*********************************************************************
  140. COMMAND
  141.      all - select and display restricted set of lines
  142.  
  143. SYNTAX
  144.      ALL [rtarget]
  145.  
  146. DESCRIPTION
  147.      The ALL command allows for the selective display, and editting
  148.      (subject to SET SCOPE) of lines that match the specified target.
  149.      This target consists of any number of individual targets
  150.      seperated by '&' (logical and) or '|' (logical or). 
  151.      For example, to display all lines in a file that contain the 
  152.      strings 'ball' and 'cat' on the same line or the named lines 
  153.      .fred or .bill, use the following command:
  154.  
  155.      ALL /ball/ & /cat/ | .fred | .bill
  156.  
  157.      Logical operators act left to right, with no precedence for &.
  158.  
  159.      ALL without any arguments, displays all lines in the file.
  160.  
  161. COMPATIBILITY
  162.      XEDIT: Compatible.
  163.      KEDIT: Compatible.
  164.  
  165. SEE ALSO
  166.      SET SCOPE, SET DISPLAY, SET SELECT
  167.  
  168. STATUS
  169.      Complete.
  170. **man-end**********************************************************************/
  171. #ifdef PROTO
  172. short All(CHARTYPE *params)
  173. #else
  174. short All(params)
  175. CHARTYPE *params;
  176. #endif
  177. /***********************************************************************/
  178. {
  179. /*-------------------------- external data ----------------------------*/
  180. /*--------------------------- local data ------------------------------*/
  181.  short rc=RC_OK;
  182.  LINE *curr=NULL;
  183.  bool target_found=FALSE,status=FALSE;
  184.  short target_type=TARGET_NORMAL;
  185.  TARGET target;
  186.  LINETYPE line_number=0L;
  187.  unsigned short x=0,y=0;
  188.  bool save_scope=FALSE;
  189.  LINETYPE num_lines=0L;
  190. /*--------------------------- processing ------------------------------*/
  191. #ifdef TRACE
  192.  trace_function("comm1.c:   All");
  193. #endif
  194.  if (strlen(params) == 0)
  195.    {
  196.     curr = CURRENT_FILE->first_line->next;
  197.     while(1)
  198.       {
  199.        curr->select = 0;
  200.        curr = curr->next;
  201.        if (curr->next == NULL)
  202.           break;
  203.       }
  204.     CURRENT_VIEW->display_low = 0;
  205.     CURRENT_VIEW->display_high = 0;
  206.     build_current_screen(); 
  207.     display_current_screen();
  208. #ifdef TRACE
  209.     trace_return();
  210. #endif
  211.     return(rc);
  212.    }
  213. /*---------------------------------------------------------------------*/
  214. /* Validate the parameters as valid targets...                         */
  215. /*---------------------------------------------------------------------*/
  216.  initialise_target(&target);
  217.  rc = parse_target(params,get_true_line(),&target,target_type,TRUE,TRUE);
  218.  if (rc != RC_OK)
  219.    {
  220.     free_target(&target);
  221. #ifdef TRACE
  222.     trace_return();
  223. #endif
  224.     return(RC_INVALID_OPERAND);
  225.    }
  226. /*---------------------------------------------------------------------*/
  227. /* Save the select levels for all lines in case no target is found.    */
  228. /*---------------------------------------------------------------------*/
  229.  curr = CURRENT_FILE->first_line->next;
  230.  while(1)
  231.    {
  232.     curr->save_select = curr->select;
  233.     curr = curr->next;
  234.     if (curr->next == NULL)
  235.        break;
  236.    }
  237. /*---------------------------------------------------------------------*/
  238. /* Find all lines for the supplied target...                           */
  239. /*---------------------------------------------------------------------*/
  240.  curr = CURRENT_FILE->first_line;
  241.  status = FALSE;
  242.  save_scope = CURRENT_VIEW->scope_all;
  243.  CURRENT_VIEW->scope_all = TRUE;
  244.  for (line_number=0L;curr->next != NULL;line_number++)
  245.    {
  246.     status = find_rtarget_target(curr,&target,0L,line_number,&num_lines);
  247.     if (status)
  248.       {
  249.        target_found = TRUE;
  250.        curr->select = 1;
  251.       }
  252.     else
  253.        curr->select = 0;
  254.     curr = curr->next;
  255.    }
  256. /*---------------------------------------------------------------------*/
  257. /* If at least one line matches the target, set DISPLAY to 1 1,        */
  258. /* otherwise reset the select levels as they were before the command.  */
  259. /*---------------------------------------------------------------------*/
  260.  if (target_found)
  261.    {
  262.     post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  263.     CURRENT_VIEW->display_low = 1;
  264.     CURRENT_VIEW->display_high = 1;
  265.     CURRENT_VIEW->scope_all = FALSE;
  266.     CURRENT_VIEW->current_line = find_next_in_scope(CURRENT_FILE->first_line->next,1L,DIRECTION_FORWARD);
  267.     build_current_screen(); 
  268.     display_current_screen();
  269.     CURRENT_VIEW->focus_line = calculate_focus_line(CURRENT_VIEW->focus_line,
  270.                                                     CURRENT_VIEW->current_line);
  271.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  272.     if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
  273.       {
  274.        getyx(CURRENT_WINDOW,y,x);
  275.        y = get_row_for_focus_line(CURRENT_VIEW->focus_line,
  276.                                   CURRENT_VIEW->current_row);
  277.        wmove(CURRENT_WINDOW,y,x);
  278.       }
  279.    }
  280.   else
  281.    {
  282.     CURRENT_VIEW->scope_all = save_scope;
  283.     curr = CURRENT_FILE->first_line->next;
  284.     while(1)
  285.       {
  286.        curr->select = curr->save_select;
  287.        curr = curr->next;
  288.        if (curr->next == NULL)
  289.           break;
  290.       }
  291.     display_error(17,params,FALSE);
  292.     rc = RC_TARGET_NOT_FOUND;
  293.    }
  294.  free_target(&target);
  295. #ifdef TRACE
  296.  trace_return();
  297. #endif
  298.  return(rc);
  299. }
  300. /*man-start*********************************************************************
  301. COMMAND
  302.      backward - scroll backwards [n] screens
  303.  
  304. SYNTAX
  305.      BAckward [n|*]
  306.  
  307. DESCRIPTION
  308.      The BACKWARD command scrolls the file contents backwards through
  309.      the file [n|*] screens.
  310.  
  311.      If 0 is specified as the number of screens to scroll, the last
  312.      line of the file becomes the current line. 
  313.      If the BACKWARD command is issued while the current line is
  314.      the "Top of File" line, the last line of the file becomes the 
  315.      current line.
  316.  
  317. COMPATIBILITY
  318.      XEDIT: Compatible.
  319.      KEDIT: Does not support HALF or Lines options.
  320.  
  321. DEFAULT
  322.      1
  323.  
  324. SEE ALSO
  325.      FORWARD, TOP
  326.  
  327. STATUS
  328.      Complete
  329. **man-end**********************************************************************/
  330. #ifdef PROTO
  331. short Backward(CHARTYPE *params)
  332. #else
  333. short Backward(params)
  334. CHARTYPE *params;
  335. #endif
  336. /***********************************************************************/
  337. {
  338. /*-------------------------- external data ----------------------------*/
  339.  extern bool curses_started;
  340. /*--------------------------- local data ------------------------------*/
  341. #define BAC_PARAMS  1
  342.  CHARTYPE *word[BAC_PARAMS+1];
  343.  unsigned short num_params=0;
  344.  LINETYPE num_pages=0L;
  345.  unsigned short x=0,y=0;
  346.  short rc=RC_OK;
  347.  short direction=0;
  348. /*--------------------------- processing ------------------------------*/
  349. #ifdef TRACE
  350.  trace_function("comm1.c:   Backward");
  351. #endif
  352. /*---------------------------------------------------------------------*/
  353. /* Validate parameters...                                              */
  354. /*---------------------------------------------------------------------*/
  355.  num_params = param_split(params,word,BAC_PARAMS,WORD_DELIMS,TEMP_PARAM);
  356.  if (num_params == 0)
  357.     {
  358.      num_params = 1;
  359.      word[0] = (CHARTYPE *)"1";
  360.     }
  361.  if (num_params != 1)
  362.     {
  363.      display_error(1,(CHARTYPE *)word[1],FALSE);
  364. #ifdef TRACE
  365.     trace_return();
  366. #endif
  367.      return(RC_INVALID_OPERAND);
  368.     }
  369. /*---------------------------------------------------------------------*/
  370. /* If parameter is '*', set current line equal to "Top of File".       */
  371. /*---------------------------------------------------------------------*/
  372.  if (strcmp(word[0],"*") == 0)
  373.    {
  374.     rc = Top((CHARTYPE *)"");
  375. #ifdef TRACE
  376.     trace_return();
  377. #endif
  378.     return(rc);
  379.    }
  380. /*---------------------------------------------------------------------*/
  381. /* If the parameter is not a valid integer, error.                     */
  382. /*---------------------------------------------------------------------*/
  383.  if (!valid_integer(word[0]))
  384.    {
  385.     display_error(1,(CHARTYPE *)word[0],FALSE);
  386. #ifdef TRACE
  387.     trace_return();
  388. #endif
  389.     return(RC_INVALID_OPERAND);
  390.    }
  391. /*---------------------------------------------------------------------*/
  392. /* Number of screens to scroll is set here.                            */
  393. /*---------------------------------------------------------------------*/
  394.  num_pages = atol(word[0]);
  395. /*---------------------------------------------------------------------*/
  396. /* If the number specified is < 0, error...                            */
  397. /*---------------------------------------------------------------------*/
  398.  if (num_pages < 0L)
  399.    {
  400.     display_error(5,(CHARTYPE *)word[0],FALSE);
  401. #ifdef TRACE
  402.     trace_return();
  403. #endif
  404.     return(RC_INVALID_OPERAND);
  405.    }
  406. /*---------------------------------------------------------------------*/
  407. /* If the current line is already on "Top of File" or the parameter is */
  408. /* 0, go to the bottom of the file.                                    */
  409. /*---------------------------------------------------------------------*/
  410.  if (num_pages == 0
  411.  || CURRENT_TOF)
  412.    {
  413.     rc = Bottom((CHARTYPE *)"");
  414. #ifdef TRACE
  415.     trace_return();
  416. #endif
  417.     return(rc);
  418.    }
  419. /*---------------------------------------------------------------------*/
  420. /* Scroll the screen num_pages...                                      */
  421. /*---------------------------------------------------------------------*/
  422.  rc = scroll_page(DIRECTION_BACKWARD,num_pages,FALSE);
  423. #ifdef TRACE
  424.  trace_return();
  425. #endif
  426.  return(rc);
  427. }
  428. /*man-start*********************************************************************
  429. COMMAND
  430.      bottom - move to the bottom of the file
  431.  
  432. SYNTAX
  433.      BOTtom
  434.  
  435. DESCRIPTION
  436.      The BOTTOM command moves to the very end of the current file.
  437.      The last line of the file is set to the current line.
  438.  
  439. COMPATIBILITY
  440.      XEDIT: Compatible.
  441.      KEDIT: Compatible.
  442.  
  443. SEE ALSO
  444.      FORWARD, TOP
  445.  
  446. STATUS
  447.      Complete
  448. **man-end**********************************************************************/
  449. #ifdef PROTO
  450. short Bottom(CHARTYPE *params)
  451. #else
  452. short Bottom(params)
  453. CHARTYPE *params;
  454. #endif
  455. /***********************************************************************/
  456. {
  457. /*-------------------------- external data ----------------------------*/
  458.  extern bool in_profile;
  459.  extern bool in_macro;
  460. /*--------------------------- local data ------------------------------*/
  461.  short rc=RC_OK;
  462.  unsigned short x=0,y=0;
  463. /*--------------------------- processing ------------------------------*/
  464. #ifdef TRACE
  465.  trace_function("comm1.c:   Bottom");
  466. #endif
  467. /*---------------------------------------------------------------------*/
  468. /* No arguments are allowed; error if any are present.                 */
  469. /*---------------------------------------------------------------------*/
  470.  if (strcmp(params,"") != 0)
  471.    {
  472.     display_error(1,(CHARTYPE *)params,FALSE);
  473. #ifdef TRACE
  474.     trace_return();
  475. #endif
  476.     return(RC_INVALID_OPERAND);
  477.    }
  478.  if (CURRENT_VIEW->scope_all)
  479.     CURRENT_VIEW->current_line = CURRENT_FILE->number_lines;
  480.  else
  481.     CURRENT_VIEW->current_line = find_next_in_scope(CURRENT_FILE->last_line->prev,CURRENT_FILE->number_lines,DIRECTION_BACKWARD);
  482.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  483.  build_current_screen(); 
  484.  if (!line_in_view(CURRENT_VIEW->focus_line))
  485.     CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line;
  486.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  487.  if (!in_profile && !in_macro)
  488.    {
  489.     if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  490.        getyx(PREVIOUS_WINDOW,y,x);
  491.     else
  492.        getyx(CURRENT_WINDOW,y,x);
  493.     display_current_screen();
  494.     y = get_row_for_focus_line(CURRENT_VIEW->focus_line,
  495.                                CURRENT_VIEW->current_row);
  496.     if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  497.        wmove(PREVIOUS_WINDOW,y,x);
  498.     else
  499.        wmove(CURRENT_WINDOW,y,x);
  500.    }
  501. #ifdef TRACE
  502.  trace_return();
  503. #endif
  504.  return(rc);
  505. }
  506. /*man-start*********************************************************************
  507. COMMAND
  508.      cancel - quit from all unaltered files in the ring
  509.  
  510. SYNTAX
  511.      CANcel
  512.  
  513. DESCRIPTION
  514.      The CANCEL command exits from THE quickly by executing a QQUIT
  515.      command for every file in the ring that does not have any 
  516.      outstanding alterations.
  517.  
  518. COMPATIBILITY
  519.      XEDIT: Compatible.
  520.      KEDIT: Compatible.
  521.  
  522. SEE ALSO
  523.      CCANCEL
  524.  
  525. STATUS
  526.      Complete.
  527. **man-end**********************************************************************/
  528. #ifdef PROTO
  529. short Cancel(CHARTYPE *params)
  530. #else
  531. short Cancel(params)
  532. CHARTYPE *params;
  533. #endif
  534. /***********************************************************************/
  535. {
  536. /*-------------------------- external data ----------------------------*/
  537.  extern VIEW_DETAILS *vd_first;
  538.  extern bool curses_started;
  539.  extern CHARTYPE number_of_files;
  540.  extern CHARTYPE *temp_cmd;
  541. /*--------------------------- local data ------------------------------*/
  542.  VIEW_DETAILS *save_current_view=(VIEW_DETAILS *)NULL;
  543. /*--------------------------- processing ------------------------------*/
  544. #ifdef TRACE
  545.  trace_function("comm1.c:   Cancel");
  546. #endif
  547. /*---------------------------------------------------------------------*/
  548. /* No arguments are allowed; error if any are present.                 */
  549. /*---------------------------------------------------------------------*/
  550.  if (strcmp(params,"") != 0)
  551.    {
  552.     display_error(1,(CHARTYPE *)params,FALSE);
  553. #ifdef TRACE
  554.     trace_return();
  555. #endif
  556.     return(RC_INVALID_OPERAND);
  557.    }
  558.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  559.  CURRENT_VIEW = vd_first;
  560.  while (CURRENT_VIEW != (VIEW_DETAILS *)NULL)
  561.    {
  562.     if (CURRENT_FILE->save_alt == 0)
  563.        free_view_memory();
  564.     else
  565.       {
  566.        save_current_view = CURRENT_VIEW;
  567.        CURRENT_VIEW = CURRENT_VIEW->next;
  568.       }
  569.    }
  570.  if (save_current_view != (VIEW_DETAILS *)NULL)
  571.    {
  572.     CURRENT_VIEW = save_current_view;
  573.     CURRENT_SCREEN.screen_view = CURRENT_VIEW;
  574.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  575.     build_current_screen(); 
  576.     display_current_screen();
  577.     if (curses_started)
  578.       {
  579.        if (CURRENT_WINDOW_PREFIX != NULL)
  580.           touchwin(CURRENT_WINDOW_PREFIX);
  581.        if (CURRENT_WINDOW_COMMAND != NULL)
  582.           touchwin(CURRENT_WINDOW_COMMAND);
  583.        touchwin(CURRENT_WINDOW_MAIN);
  584.        touchwin(CURRENT_WINDOW);
  585.       }
  586.    }
  587.  if (number_of_files > 0)
  588.    {
  589.     sprintf(temp_cmd,"%d file(s) remain with outstanding changes",number_of_files);
  590.     display_error(0,(CHARTYPE *)temp_cmd,TRUE);
  591.    }
  592. #ifdef TRACE
  593.  trace_return();
  594. #endif
  595.  return(QUIT);
  596. }
  597. /*man-start*********************************************************************
  598. COMMAND
  599.      ccancel - qquit from all files in the ring
  600.  
  601. SYNTAX
  602.      CCancel
  603.  
  604. DESCRIPTION
  605.      The CCANCEL command exits from THE quickly by executing the QQUIT
  606.      command for every file in the ring. Any changes made to any of 
  607.      the files will be lost.
  608.  
  609. COMPATIBILITY
  610.      XEDIT: N/A
  611.      KEDIT: N/A
  612.  
  613. SEE ALSO
  614.      CANCEL
  615.  
  616. STATUS
  617.      Complete.
  618. **man-end**********************************************************************/
  619. #ifdef PROTO
  620. short Ccancel(CHARTYPE *params)
  621. #else
  622. short Ccancel(params)
  623. CHARTYPE *params;
  624. #endif
  625. /***********************************************************************/
  626. {
  627. /*-------------------------- external data ----------------------------*/
  628.  extern VIEW_DETAILS *vd_first;
  629. /*--------------------------- local data ------------------------------*/
  630. /*--------------------------- processing ------------------------------*/
  631. #ifdef TRACE
  632.  trace_function("comm1.c:   Ccancel");
  633. #endif
  634. /*---------------------------------------------------------------------*/
  635. /* No arguments are allowed; error if any are present.                 */
  636. /*---------------------------------------------------------------------*/
  637.  if (strcmp(params,"") != 0)
  638.    {
  639.     display_error(1,(CHARTYPE *)params,FALSE);
  640. #ifdef TRACE
  641.     trace_return();
  642. #endif
  643.     return(RC_INVALID_OPERAND);
  644.    }
  645.  CURRENT_VIEW = vd_first;
  646.  while (CURRENT_VIEW != (VIEW_DETAILS *)NULL)
  647.    {
  648.     free_view_memory();
  649.    }
  650. #ifdef TRACE
  651.  trace_return();
  652. #endif
  653.  return(QUIT);
  654. }
  655. /*man-start*********************************************************************
  656. COMMAND
  657.      change - change one string to another
  658.  
  659. SYNTAX
  660.      Change /string1/string2/ [target] [n] [m]
  661.  
  662. DESCRIPTION
  663.      The CHANGE command changes one string of text to another.
  664.  
  665.      The first parameter to the change command is the old and new
  666.      string values, seperated by delimiters.
  667.      The allowable delimiters are '/' '\' and '@'.
  668.  
  669.      The second parameter is the target; how many lines are to be
  670.      searched for occurrences of the first string to be changed.
  671.  
  672.      The third parameter determines how many occurrences of 'string1'
  673.      are to be changed on each line.
  674.  
  675.      The fourth parameter determines at which occurrences of 'string1'
  676.      on the line are changes to commence.
  677.  
  678. COMPATIBILITY
  679.      XEDIT: Compatible.
  680.      KEDIT: Compatible.
  681.  
  682. DEFAULT
  683.      1 1 1
  684.  
  685. SEE ALSO
  686.      SCHANGE
  687.  
  688. STATUS
  689.      Complete.
  690. **man-end**********************************************************************/
  691. #ifdef PROTO
  692. short Change(CHARTYPE *params)
  693. #else
  694. short Change(params)
  695. CHARTYPE *params;
  696. #endif
  697. /***********************************************************************/
  698. {
  699. /*--------------------------- local data ------------------------------*/
  700.  short rc=RC_OK;
  701. /*--------------------------- processing ------------------------------*/
  702. #ifdef TRACE
  703.  trace_function("comm1.c:   Change");
  704. #endif
  705.  rc = execute_change_command(params,FALSE);
  706. #ifdef TRACE
  707.  trace_return();
  708. #endif
  709.  return(rc);
  710. }
  711. /*man-start*********************************************************************
  712. COMMAND
  713.      cmatch - find matching bracket character
  714.  
  715. SYNTAX
  716.      cmatch 
  717.  
  718. DESCRIPTION
  719.      The CMATCH command searches for the matching bracket character to
  720.      the character under the cursor.
  721.  
  722.      It handles nested sets of matching pairs.
  723.      The matching character pairs are '[]{}<>()'.
  724.  
  725.      This command can only be used by assigning it to a function key
  726.      with the DEFINE command.
  727.  
  728. COMPATIBILITY
  729.      XEDIT: N/A
  730.      KEDIT: Compatible.
  731.  
  732. STATUS
  733.      Complete.
  734. **man-end**********************************************************************/
  735. #ifdef PROTO
  736. short Cmatch(CHARTYPE *params)
  737. #else
  738. short Cmatch(params)
  739. CHARTYPE *params;
  740. #endif
  741. /***********************************************************************/
  742. {
  743. /*------------------------- external data -----------------------------*/
  744.  extern bool in_profile;
  745. /*--------------------------- local data ------------------------------*/
  746.  static CHARTYPE *match = (CHARTYPE *)"[]{}<>()";
  747.  unsigned short x=0,y=0;
  748.  CHARTYPE ch=0,match_ch=0;
  749.  register short i=0;
  750.  short direction_backward=0;
  751.  short matches=1,match_col=(-1),start_col=0;
  752.  LINETYPE offset=0L;
  753.  LINE *curr=NULL;
  754.  WINDOW *w=NULL;
  755. /*--------------------------- processing ------------------------------*/
  756. #ifdef TRACE
  757.  trace_function("comm1.c:   Cmatch");
  758. #endif
  759. /*---------------------------------------------------------------------*/
  760. /* This command only allowed to be issued from with the MAIN window.   */
  761. /*---------------------------------------------------------------------*/
  762.  if (CURRENT_VIEW->current_window != WINDOW_MAIN
  763.  || in_profile)
  764.    {
  765.     display_error(66,(CHARTYPE *)"",FALSE);
  766. #ifdef TRACE
  767.     trace_return();
  768. #endif
  769.     return(RC_INVALID_ENVIRON);
  770.    }
  771. /*---------------------------------------------------------------------*/
  772. /* This command cannot be issued on TOF or BOF.                        */
  773. /*---------------------------------------------------------------------*/
  774.  if (FOCUS_TOF
  775.  ||  FOCUS_BOF)
  776.    {
  777.     display_error(66,(CHARTYPE *)"",FALSE);
  778. #ifdef TRACE
  779.     trace_return();
  780. #endif
  781.     return(RC_TOF_EOF_REACHED);
  782.    }
  783.  getyx(CURRENT_WINDOW,y,x);
  784. /*---------------------------------------------------------------------*/
  785. /* This command cannot be entered on a shadow line.                    */
  786. /*---------------------------------------------------------------------*/
  787.  if (CURRENT_SCREEN.sl[y].line_type == LINE_SHADOW)
  788.    {
  789.     display_error(87,(CHARTYPE *)"",FALSE);
  790. #ifdef TRACE
  791.     trace_return();
  792. #endif
  793.     return(RC_TARGET_NOT_FOUND);
  794.    }
  795. /*---------------------------------------------------------------------*/
  796. /* Check if the character under the cursor is a valid match character. */
  797. /*---------------------------------------------------------------------*/
  798.  w = CURRENT_WINDOW;
  799.  ch = (CHARTYPE)winch(w) & A_CHARTEXT;
  800.  match_ch = 0;
  801.  for (i=0;i<strlen(match);i++)
  802.     if (ch == *(match+i))
  803.       {
  804.        direction_backward = (i % 2);
  805.        match_ch = (direction_backward) ? *(match+i-1) : *(match+i+1);
  806.        break;
  807.       }
  808.  if (match_ch == 0)
  809.    {
  810.     display_error(67,(CHARTYPE *)"",FALSE);
  811. #ifdef TRACE
  812.     trace_return();
  813. #endif
  814.     return(RC_INVALID_OPERAND);
  815.    }
  816. /*---------------------------------------------------------------------*/
  817. /* Calculate the actual position of the character in the LINE.         */
  818. /*---------------------------------------------------------------------*/
  819.  start_col = CURRENT_VIEW->verify_col + x - 1;
  820.  start_col += (direction_backward) ? (-1) : 1;
  821. /*---------------------------------------------------------------------*/
  822. /* Find the focus line linked list entry.                              */
  823. /*---------------------------------------------------------------------*/
  824.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  825.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
  826.  while (curr->next != NULL && curr->prev != NULL)
  827.    {
  828.     if (direction_backward)
  829.       {
  830.        for (i=start_col;i>(-1);i--)
  831.           {
  832.            if (*(curr->line+i) == ch)
  833.              matches++;
  834.            else
  835.               if (*(curr->line+i) == match_ch)
  836.                 matches--;
  837.            if (matches == 0)       /* found matching one */
  838.              {
  839.               match_col = i;
  840.               break;
  841.              }
  842.           }
  843.        if (match_col != (-1))
  844.          break;
  845.        curr = curr->prev;
  846.        offset--;
  847.        start_col = curr->length;
  848.       }
  849.     else
  850.       {
  851.        for (i=start_col;i<curr->length;i++)
  852.           {
  853.            if (*(curr->line+i) == ch)
  854.              matches++;
  855.            else
  856.               if (*(curr->line+i) == match_ch)
  857.                 matches--;
  858.            if (matches == 0)       /* found matching one */
  859.              {
  860.               match_col = i;
  861.               break;
  862.              }
  863.           }
  864.        if (match_col != (-1))
  865.          break;
  866.        curr = curr->next;
  867.        offset++;
  868.        start_col = 0;
  869.       }
  870.    }
  871. /*---------------------------------------------------------------------*/
  872. /* If no match found, return with error.                               */
  873. /*---------------------------------------------------------------------*/
  874.  if (match_col == (-1))  /* no match found */
  875.    {
  876.     display_error(68,(CHARTYPE *)"",FALSE);
  877. #ifdef TRACE
  878.     trace_return();
  879. #endif
  880.     return(RC_TARGET_NOT_FOUND);
  881.    }
  882. /*---------------------------------------------------------------------*/
  883. /* If we get here, we have found the matching character, so we have to */
  884. /*  move the cursor to the new column and/or line.                     */
  885. /*---------------------------------------------------------------------*/
  886.  if (offset == 0L)
  887.    {
  888.     if (match_col >= CURRENT_VIEW->verify_col-1
  889.     &&  match_col <= (CURRENT_SCREEN.cols[WINDOW_MAIN]+(CURRENT_VIEW->verify_col-1))-1)
  890. /*---------------------------------------------------------------------*/
  891. /* If the new cursor position is in the same panel and on the same line*/
  892. /* just move the cursor there and get out.                             */
  893. /*---------------------------------------------------------------------*/
  894.       {
  895.        wmove(CURRENT_WINDOW,y,match_col-(CURRENT_VIEW->verify_col-1));
  896. #ifdef TRACE
  897.        trace_return();
  898. #endif
  899.        return(RC_OK);
  900.       }
  901.    else
  902.       {
  903.        x = CURRENT_SCREEN.cols[WINDOW_MAIN] / 2;
  904.        CURRENT_VIEW->verify_col = max(1,match_col-(short)x);
  905.        build_current_screen(); 
  906.        display_current_screen();
  907.        wmove(CURRENT_WINDOW,y,(match_col-(CURRENT_VIEW->verify_col-1)));
  908. #ifdef TRACE
  909.        trace_return();
  910. #endif
  911.        return(RC_OK);
  912.       }
  913.    }
  914. /*---------------------------------------------------------------------*/
  915. /* If a match IS found on a different line, further checks are required*/
  916. /* for SCOPE.                                                          */
  917. /*---------------------------------------------------------------------*/
  918.  if (in_scope(curr))
  919.    {
  920. /*---------------------------------------------------------------------*/
  921. /* Set the cursor position for the matching character.                 */
  922. /*---------------------------------------------------------------------*/
  923.     CURRENT_VIEW->focus_line += offset;
  924.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  925.     if (line_in_view(CURRENT_VIEW->focus_line))
  926.        y = get_row_for_focus_line(CURRENT_VIEW->focus_line,
  927.                                   CURRENT_VIEW->current_row);
  928.     else
  929.       {
  930.        CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
  931.        y = CURRENT_VIEW->current_row;
  932.       }
  933.    }
  934.  else
  935.     if (CURRENT_VIEW->scope_all)
  936.       {
  937.        curr->select = CURRENT_VIEW->display_low;
  938.        CURRENT_VIEW->focus_line += offset;
  939.        CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
  940.        pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  941.        y = CURRENT_VIEW->current_row;
  942.       }
  943.     else
  944.       {
  945.        display_error(68,(CHARTYPE *)"",FALSE);
  946. #ifdef TRACE
  947.        trace_return();
  948. #endif
  949.        return(RC_TARGET_NOT_FOUND);
  950.       }
  951. #if 0
  952.  if (offset + y < 0
  953.  ||  offset + y >= CURRENT_SCREEN.rows)
  954.    {
  955.     CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
  956.     y = CURRENT_VIEW->current_row;
  957.    }
  958.  else
  959.     y = get_row_for_focus_line(CURRENT_VIEW->focus_line,
  960.                                CURRENT_VIEW->current_row);
  961. #endif
  962.  if (match_col >= CURRENT_VIEW->verify_col-1
  963.  &&  match_col <= (CURRENT_SCREEN.cols[WINDOW_MAIN]+(CURRENT_VIEW->verify_col-1))-1)
  964.     x = match_col-(CURRENT_VIEW->verify_col-1);
  965.  else
  966.    {
  967.     x = CURRENT_SCREEN.cols[WINDOW_MAIN] / 2;
  968.     CURRENT_VIEW->verify_col = max(1,match_col-(short)x);
  969.     x = (match_col-(CURRENT_VIEW->verify_col-1));
  970.    }
  971.  
  972.  build_current_screen(); 
  973.  display_current_screen();
  974.  wmove(CURRENT_WINDOW,y,x);
  975. #ifdef TRACE
  976.  trace_return();
  977. #endif
  978.  return(RC_OK);
  979. }
  980. /*man-start*********************************************************************
  981. COMMAND
  982.      cmsg - display text on command line
  983.  
  984. SYNTAX
  985.      CMSG [text]
  986.  
  987. DESCRIPTION
  988.      The CMSG command, primarily used in macros, displays text on the
  989.      command line.
  990.  
  991. COMPATIBILITY
  992.      XEDIT: Compatible.
  993.      KEDIT: Compatible.
  994.  
  995. SEE ALSO
  996.      EMSG, MSG
  997.  
  998. STATUS
  999.      Complete.
  1000. **man-end**********************************************************************/
  1001. #ifdef PROTO
  1002. short Cmsg(CHARTYPE *params)
  1003. #else
  1004. short Cmsg(params)
  1005. CHARTYPE *params;
  1006. #endif
  1007. /***********************************************************************/
  1008. {
  1009. /*------------------------- external data -----------------------------*/
  1010.  extern CHARTYPE *cmd_rec;
  1011.  extern LENGTHTYPE cmd_rec_len;
  1012.  extern bool clear_command;
  1013.  extern bool ETMODEx;
  1014.  register short i;
  1015. /*--------------------------- local data ------------------------------*/
  1016. /*--------------------------- processing ------------------------------*/
  1017. #ifdef TRACE
  1018.  trace_function("comm1.c:   Cmsg");
  1019. #endif
  1020.  memset(cmd_rec,' ',COLS);
  1021.  cmd_rec_len = strlen(params);
  1022.  memcpy(cmd_rec,params,cmd_rec_len);
  1023.  wmove(CURRENT_WINDOW_COMMAND,0,0);
  1024.  my_wclrtoeol(CURRENT_WINDOW_COMMAND);
  1025. /*---------------------------------------------------------------------*/
  1026. /* If the terminal is in ETMODE, display all characters as is, else    */
  1027. /* display message with translation of non-displaying characters.      */
  1028. /*---------------------------------------------------------------------*/
  1029.  if (ETMODEx)
  1030.    {
  1031.     for (i=0;i<cmd_rec_len;i++)
  1032.         mvwaddch(CURRENT_WINDOW_COMMAND,0,i,cmd_rec[i]);
  1033.    }
  1034.  else
  1035.     put_string(CURRENT_WINDOW_COMMAND,0,0,cmd_rec,cmd_rec_len);
  1036.  clear_command = FALSE;
  1037. #ifdef TRACE
  1038.  trace_return();
  1039. #endif
  1040.  return(RC_OK);
  1041. }
  1042. /*man-start*********************************************************************
  1043. COMMAND
  1044.      command - execute a command without translation
  1045.  
  1046. SYNTAX
  1047.      COMMAND command [options]
  1048.  
  1049. DESCRIPTION
  1050.      The COMMAND command executes the specified command without
  1051.      synonym or macro translation. THE does not attempt to execute 
  1052.      the command as a macro even if IMPMACRO is ON. The command will 
  1053.      be passed to the operating system if IMPOS is ON.
  1054.  
  1055. COMPATIBILITY
  1056.      XEDIT: Compatible.
  1057.      KEDIT: Compatible.
  1058.  
  1059. STATUS
  1060.      Complete.
  1061. **man-end**********************************************************************/
  1062. #ifdef PROTO
  1063. short THECommand(CHARTYPE *params)
  1064. #else
  1065. short THECommand(params)
  1066. CHARTYPE *params;
  1067. #endif
  1068. /***********************************************************************/
  1069. {
  1070. /*------------------------- external data -----------------------------*/
  1071. /*--------------------------- local data ------------------------------*/
  1072.  short rc=RC_OK;
  1073. /*--------------------------- processing ------------------------------*/
  1074. #ifdef TRACE
  1075.  trace_function("comm1.c:   THECommand");
  1076. #endif
  1077.  rc = command_line(params,COMMAND_ONLY_TRUE);
  1078. #ifdef TRACE
  1079.  trace_return();
  1080. #endif
  1081.  return(rc);
  1082. }
  1083. /*man-start*********************************************************************
  1084. COMMAND
  1085.      control_char - allow control characters to be entered
  1086.  
  1087. SYNTAX
  1088.      control_char
  1089.  
  1090. DESCRIPTION
  1091.      The CONTROL_CHAR command prompts the user to enter a control 
  1092.      character.
  1093.  
  1094.      This command can only be used by assigning it to a function key
  1095.      with the DEFINE command.
  1096.  
  1097. COMPATIBILITY
  1098.      XEDIT: N/A
  1099.      KEDIT: N/A
  1100.  
  1101. STATUS
  1102.      Complete.
  1103. **man-end**********************************************************************/
  1104. #ifdef PROTO
  1105. short Control_char(CHARTYPE *params)
  1106. #else
  1107. short Control_char(params)
  1108. CHARTYPE *params;
  1109. #endif
  1110. /***********************************************************************/
  1111. {
  1112. /*------------------------- external data -----------------------------*/
  1113. /*--------------------------- local data ------------------------------*/
  1114.  unsigned short y=0,x=0;
  1115.  int key=0;
  1116. /*--------------------------- processing ------------------------------*/
  1117. #ifdef TRACE
  1118.  trace_function("comm1.c:   Control_char");
  1119. #endif
  1120. /*---------------------------------------------------------------------*/
  1121. /* If in the MAIN window, this command can only be issued on a real    */
  1122. /* line.                                                               */
  1123. /*---------------------------------------------------------------------*/
  1124.  if (CURRENT_VIEW->current_window == WINDOW_MAIN)
  1125.    {
  1126.     getyx(CURRENT_WINDOW,y,x);
  1127.     if (CURRENT_SCREEN.sl[y].line_type != LINE_LINE)
  1128.       {
  1129.        display_error(38,(CHARTYPE *)"",FALSE);
  1130. #ifdef TRACE
  1131.        trace_return();
  1132. #endif
  1133.        return(RC_INVALID_ENVIRON);
  1134.       }
  1135.    }
  1136.  display_prompt("Press the character you require.");
  1137.  key = my_getch(CURRENT_WINDOW);
  1138.  clear_msgline();
  1139.  if (islower(key))
  1140.     key = toupper(key);
  1141.  if (key >= (int)'@'
  1142.  &&  key <= (int)'_')
  1143.    {
  1144. #ifdef TRACE
  1145.     trace_return();
  1146. #endif
  1147.     return((RAW_KEY*2)+(short)key-(short)'@');
  1148.    }
  1149.  display_error(69,(CHARTYPE *)"- must be between '@' and '_'",FALSE);
  1150. #ifdef TRACE
  1151.  trace_return();
  1152. #endif
  1153.  return(RC_INVALID_OPERAND);
  1154. }
  1155. /*man-start*********************************************************************
  1156. COMMAND
  1157.      copy - copies text from one position to another
  1158.  
  1159. SYNTAX
  1160.      COPY target1 target2
  1161.      COPY BLOCK [RESET]
  1162.  
  1163. DESCRIPTION
  1164.      With the first form of the COPY command, text is copied from the
  1165.      first target area to the line specified by target2. Text can
  1166.      only be copied within the same view of the file.
  1167.  
  1168.      The second form of the COPY command copies text within the
  1169.      currently marked block to the current cursor position.
  1170.      The text can be in the same file or a different file.
  1171.  
  1172. COMPATIBILITY
  1173.      XEDIT: COPY BLOCK not available.
  1174.      KEDIT: Adds extra functionality with [RESET] option.
  1175.             With the cursor in the marked block this command in KEDIT
  1176.             acts like DUPLICATE BLOCK.
  1177.  
  1178. STATUS
  1179.      Complete.
  1180. **man-end**********************************************************************/
  1181. #ifdef PROTO
  1182. short Copy(CHARTYPE *params)
  1183. #else
  1184. short Copy(params)
  1185. CHARTYPE *params;
  1186. #endif
  1187. /***********************************************************************/
  1188. {
  1189. /*-------------------------- external data ----------------------------*/
  1190.  extern VIEW_DETAILS *vd_mark;
  1191. /*--------------------------- local data ------------------------------*/
  1192.  CHARTYPE reset_block=SOURCE_UNKNOWN;
  1193.  short rc=RC_OK;
  1194.  LINETYPE start_line=0L,end_line=0L,true_line=0L;
  1195.  VIEW_DETAILS *source_view=NULL,*dest_view=NULL;
  1196.  TARGET target1,target2;
  1197.  short target_type1=TARGET_NORMAL|TARGET_BLOCK_ANY|TARGET_ALL|TARGET_SPARE;
  1198.  short target_type2=TARGET_NORMAL;
  1199.  bool lines_based_on_scope=FALSE;
  1200. /*--------------------------- processing ------------------------------*/
  1201. #ifdef TRACE
  1202.  trace_function("comm1.c:   Copy");
  1203. #endif
  1204.  initialise_target(&target1);
  1205.  initialise_target(&target2);
  1206.  if ((rc = validate_target(params,&target1,target_type1,get_true_line(),TRUE,TRUE)) != RC_OK)
  1207.    {
  1208.     free_target(&target1);
  1209. #ifdef TRACE
  1210.     trace_return();
  1211. #endif
  1212.     return(rc);
  1213.    }
  1214. /*---------------------------------------------------------------------*/
  1215. /* If there is no second argument, the only valid target type for the  */
  1216. /* first argument then is BLOCK.                                       */
  1217. /*---------------------------------------------------------------------*/
  1218.  if (target1.spare == (-1))
  1219.    {
  1220.     if (target1.rt[0].target_type != TARGET_BLOCK_ANY
  1221.     &&  target1.rt[0].target_type != TARGET_BLOCK_CURRENT)
  1222.       {
  1223.        free_target(&target1);
  1224.        display_error(3,(CHARTYPE *)"",FALSE);
  1225. #ifdef TRACE
  1226.        trace_return();
  1227. #endif
  1228.        return(RC_INVALID_OPERAND);
  1229.       }
  1230.     else
  1231.        reset_block = SOURCE_BLOCK;
  1232.    }
  1233.  else
  1234.    {
  1235.     if (equal((CHARTYPE *)"reset",strtrunc(target1.rt[target1.spare].string),5))
  1236.        reset_block = SOURCE_BLOCK_RESET;
  1237.     else
  1238.        reset_block = SOURCE_COMMAND;
  1239.    }
  1240. /*---------------------------------------------------------------------*/
  1241. /* Validate the arguments following the target...                      */
  1242. /*---------------------------------------------------------------------*/
  1243.  switch(reset_block)
  1244.    {
  1245.     case SOURCE_BLOCK:
  1246.     case SOURCE_BLOCK_RESET:
  1247. /*---------------------------------------------------------------------*/
  1248. /* For box blocks, call the appropriate function...                    */
  1249. /*---------------------------------------------------------------------*/
  1250.          if (MARK_VIEW->mark_type != M_LINE)
  1251.            {
  1252.             free_target(&target1);
  1253.             box_operations(BOX_C,reset_block,FALSE,' ');
  1254. #ifdef TRACE
  1255.             trace_return();
  1256. #endif
  1257.             return(RC_OK);
  1258.            }
  1259.          source_view = MARK_VIEW;
  1260.          dest_view = CURRENT_VIEW;
  1261.          start_line = MARK_VIEW->mark_start_line;
  1262.          end_line = MARK_VIEW->mark_end_line;
  1263.          true_line = get_true_line();
  1264.          lines_based_on_scope = FALSE;
  1265.          break;
  1266.     default:
  1267.          if ((rc = validate_target(target1.rt[target1.spare].string,&target2,target_type2,get_true_line(),TRUE,TRUE)) != RC_OK)
  1268.            {
  1269.             free_target(&target2);
  1270. #ifdef TRACE
  1271.             trace_return();
  1272. #endif
  1273.             return(rc);
  1274.            }
  1275.          source_view = CURRENT_VIEW;
  1276.          dest_view = CURRENT_VIEW;
  1277. #if 0
  1278.          if (TOF(target1.true_line))
  1279.            {
  1280.             target1.true_line = 1L;
  1281.             target1.num_lines--;
  1282.            }
  1283. #endif
  1284.          start_line = target1.true_line;
  1285.          end_line = (target1.true_line + target1.num_lines) - 1L;
  1286.          true_line = target2.true_line + target2.num_lines;
  1287.          lines_based_on_scope = TRUE;
  1288.          break;
  1289.    }
  1290.  free_target(&target1);
  1291.  free_target(&target2);
  1292. /*---------------------------------------------------------------------*/
  1293. /* If the destination line for the copy is the *** Bottom of File ***  */
  1294. /* line, then subtract 1 to ensure lines don't get copied below the    */
  1295. /* *** Bottom of File *** line.                                        */
  1296. /*---------------------------------------------------------------------*/
  1297.  if (BOF(true_line))
  1298.     true_line--;
  1299.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  1300.  rc = rearrange_line_blocks(COMMAND_COPY,(CHARTYPE)reset_block,start_line,
  1301.                             end_line,true_line,1,source_view,dest_view,lines_based_on_scope);
  1302.  
  1303. #ifdef TRACE
  1304.  trace_return();
  1305. #endif
  1306.  return(rc);
  1307. }
  1308. /*man-start*********************************************************************
  1309. COMMAND
  1310.      cursor - move cursor to specified position
  1311.  
  1312. SYNTAX
  1313.      CURsor Screen UP|DOWN|LEFT|RIGHT
  1314.      CURsor Screen row [col]
  1315.      CURsor [Escreen] UP|DOWN
  1316.      CURsor [Escreen|Kedit] LEFT|RIGHT
  1317.      CURsor [Escreen] row [col]
  1318.      CURsor CMdline [n]
  1319.      CURsor HOME [SAVE]
  1320.  
  1321. DESCRIPTION
  1322.      The CURSOR command allows the user to specify where the cursor
  1323.      is to be positioned.
  1324.  
  1325.      CURSOR SCREEN UP|DOWN|LEFT|RIGHT moves the cursor in the
  1326.      indicated direction one line or column. If the cursor is
  1327.      positioned on the first or last line of the screen, the cursor
  1328.      wraps to the first or last enterable lines. If the cursor is
  1329.      positioned on the left or right edges of the screen, the cursor
  1330.      moves to the left or right edge of the screen on the same line.
  1331.  
  1332.      CURSOR SCREEN row [col] moves the cursor to the specified
  1333.      row/col position within the file area. The top left corner of
  1334.      the file area is 1,1.
  1335.      row and col may be specified as '=', which will default to the
  1336.      current row and/or column position.
  1337.      If row or col are greater than the maximum number of rows or
  1338.      columns in the file area, the cursor will move to the last 
  1339.      row/column available.
  1340.      If the specified row is a reserved line, scale line or tab line
  1341.      an error will be displayed.
  1342.      If the row specified is above "Top of File" or below
  1343.      "Bottom of File" the cursor will be placed on the appropriate
  1344.      line.
  1345.  
  1346.      CURSOR [ESCREEN] UP|DOWN|LEFT|RIGHT is similar to CURSOR SCREEN
  1347.      UP|DOWN|LEFT|RIGHT, except that where scrolling of the window is
  1348.      possible, then scrolling will take place.
  1349.  
  1350.      CURSOR [ESCREEN] row [col] is similar to CURSOR SCREEN row [col],
  1351.      but all coordinates are relative the the top left corner of the
  1352.      logical window, not the top left corner of the file area. Hence,
  1353.      1,1 would be an invalid cursor position because it would result
  1354.      in the cursor being moved to the id line.
  1355.      Specification of row and/or column outside the boundaries of the
  1356.      logical window is regarded as an error.
  1357.  
  1358.      CURSOR KEDIT LEFT|RIGHT mimics the default behaviour of CURL and
  1359.      CURR in KEDIT.
  1360.  
  1361.      CURSOR CMDMLINE moves the cursor to the indicated column of the
  1362.      command line.
  1363.  
  1364.      CURsor HOME moves the cursor to the first column of the command
  1365.      line (if not on the command line), or to the last row/column of
  1366.      the file area if on the command line. With the [SAVE] option,
  1367.      the cursor will move to the last row/column of the file area or
  1368.      prefix area (which ever was the last position) if on the
  1369.      command line.
  1370.  
  1371.  
  1372. COMPATIBILITY
  1373.      XEDIT: Does not support COLUMN or FILE options.
  1374.      KEDIT: Does not support COLUMN or FILE options.
  1375.  
  1376. STATUS
  1377.      Complete.
  1378. **man-end**********************************************************************/
  1379. #ifdef PROTO
  1380. short Cursor(CHARTYPE *params)
  1381. #else
  1382. short Cursor(params)
  1383. CHARTYPE *params;
  1384. #endif
  1385. /***********************************************************************/
  1386. {
  1387. /*--------------------------- local data ------------------------------*/
  1388.  register short idx=0;
  1389. #define CUR_PARAMS  3
  1390.  CHARTYPE *word[CUR_PARAMS+1];
  1391.  unsigned short num_params=0;
  1392.  bool time_to_leave=FALSE;
  1393.  bool escreen=FALSE;
  1394.  short error_number=1;
  1395.  CHARTYPE *error_message=(CHARTYPE *)"";
  1396.  short colno=1;
  1397.  short rc=RC_OK;
  1398.  short state=CURSOR_START;
  1399.  short row=0,col=0;
  1400. /*--------------------------- processing ------------------------------*/
  1401. #ifdef TRACE
  1402.  trace_function("comm1.c:   Cursor");
  1403. #endif
  1404.  num_params = param_split(params,word,CUR_PARAMS,WORD_DELIMS,TEMP_PARAM);
  1405.  if (num_params ==0)
  1406.    {
  1407.     display_error(3,(CHARTYPE *)"",FALSE);
  1408. #ifdef TRACE
  1409.     trace_return();
  1410. #endif
  1411.     return(RC_INVALID_OPERAND);
  1412.    }
  1413.  error_message = word[0];
  1414.  state = CURSOR_START;
  1415.  idx = 0;
  1416.  while(1)
  1417.    {
  1418.     switch(state)
  1419.       {
  1420.        case CURSOR_START:
  1421.             if (equal("escreen",word[idx],1))
  1422.               {
  1423.                state = CURSOR_ESCREEN;
  1424.                idx++;
  1425.                break;
  1426.               }
  1427.             if (equal("screen",word[idx],1))
  1428.               {
  1429.                state = CURSOR_SCREEN;
  1430.                idx++;
  1431.                break;
  1432.               }
  1433.             if (equal("kedit",word[idx],1))
  1434.               {
  1435.                state = CURSOR_KEDIT;
  1436.                idx++;
  1437.                break;
  1438.               }
  1439.             if (equal("left",word[idx],4))
  1440.               {
  1441.                if (num_params > 1)
  1442.                  {
  1443.                   state = CURSOR_ERROR;
  1444.                   error_message = word[idx];
  1445.                   error_number = 1;
  1446.                   break;
  1447.                  }
  1448.                rc = cursor_left(TRUE,FALSE);
  1449.                time_to_leave = TRUE;
  1450.                break;
  1451.               }
  1452.             if (equal("right",word[idx],5))
  1453.               {
  1454.                if (num_params > 1)
  1455.                  {
  1456.                   state = CURSOR_ERROR;
  1457.                   error_message = word[idx];
  1458.                   error_number = 1;
  1459.                   break;
  1460.                  }
  1461.                rc = cursor_right(TRUE,FALSE);
  1462.                time_to_leave = TRUE;
  1463.                break;
  1464.               }
  1465.             if (equal("up",word[idx],2))
  1466.               {
  1467.                if (num_params > 1)
  1468.                  {
  1469.                   state = CURSOR_ERROR;
  1470.                   error_message = word[idx];
  1471.                   error_number = 1;
  1472.                   break;
  1473.                  }
  1474.                rc = cursor_up(TRUE);
  1475.                time_to_leave = TRUE;
  1476.                break;
  1477.               }
  1478.             if (equal("down",word[idx],4))
  1479.               {
  1480.                if (num_params > 1)
  1481.                  {
  1482.                   state = CURSOR_ERROR;
  1483.                   error_message = word[idx];
  1484.                   error_number = 1;
  1485.                   break;
  1486.                  }
  1487.                rc = cursor_down(TRUE);
  1488.                time_to_leave = TRUE;
  1489.                break;
  1490.               }
  1491.             if (equal("home",word[idx],4))
  1492.               {
  1493.                state = CURSOR_HOME;
  1494.                idx++;
  1495.                break;
  1496.               }
  1497.             if (equal("cmdline",word[idx],2))
  1498.               {
  1499.                state = CURSOR_CMDLINE;
  1500.                idx++;
  1501.                break;
  1502.               }
  1503.             if (equal("column",word[idx],1))
  1504.               {
  1505.                state = CURSOR_ERROR;
  1506.                error_message = (CHARTYPE *)"not yet implemented";
  1507.                error_number = 0;
  1508.                break;
  1509.               }
  1510.             if (equal("file",word[idx],1))
  1511.               {
  1512.                state = CURSOR_ERROR;
  1513.                error_message = (CHARTYPE *)"not yet implemented";
  1514.                error_number = 0;
  1515.                break;
  1516.               }
  1517.             state = CURSOR_ESCREEN;
  1518.             break;
  1519.        case CURSOR_HOME:
  1520.             if (num_params > 2)
  1521.               {
  1522.                state = CURSOR_ERROR;
  1523.                error_message = word[idx];
  1524.                error_number = 1;
  1525.                break;
  1526.               }
  1527.             if (num_params == 2
  1528.             &&  !equal("save",word[1],4))
  1529.               {
  1530.                state = CURSOR_ERROR;
  1531.                error_number = 1;
  1532.                error_message = word[idx];
  1533.                break;
  1534.               }
  1535.             if (num_params == 2)
  1536.                rc = cursor_home(TRUE);
  1537.             else
  1538.                rc = cursor_home(FALSE);
  1539.             time_to_leave = TRUE;
  1540.             break;
  1541.        case CURSOR_CMDLINE:
  1542.             if (num_params > 2)
  1543.               {
  1544.                state = CURSOR_ERROR;
  1545.                error_message = word[idx];
  1546.                error_number = 1;
  1547.                break;
  1548.               }
  1549.             if (num_params == 2)
  1550.               {
  1551.                colno = atoi(word[idx]);
  1552.                if (colno < 1)
  1553.                  {
  1554.                   state = CURSOR_ERROR;
  1555.                   error_message = word[idx];
  1556.                   error_number = 1;
  1557.                   break;
  1558.                  }
  1559.               }
  1560.             rc = cursor_cmdline(colno);
  1561.             time_to_leave = TRUE;
  1562.             break;
  1563.        case CURSOR_SCREEN:
  1564.        case CURSOR_ESCREEN:
  1565.             if (state == CURSOR_ESCREEN)
  1566.                escreen = TRUE;
  1567.             else
  1568.                escreen = FALSE;
  1569.             if (equal("left",word[idx],4))
  1570.               {
  1571.                if (num_params > 2)
  1572.                  {
  1573.                   state = CURSOR_ERROR;
  1574.                   error_message = word[idx];
  1575.                   error_number = 1;
  1576.                   break;
  1577.                  }
  1578.                rc = cursor_left(escreen,FALSE);
  1579.                time_to_leave = TRUE;
  1580.                break;
  1581.               }
  1582.             if (equal("right",word[idx],5))
  1583.               {
  1584.                if (num_params > 2)
  1585.                  {
  1586.                   state = CURSOR_ERROR;
  1587.                   error_message = word[idx];
  1588.                   error_number = 1;
  1589.                   break;
  1590.                  }
  1591.                rc = cursor_right(escreen,FALSE);
  1592.                time_to_leave = TRUE;
  1593.                break;
  1594.               }
  1595.             if (equal("up",word[idx],2))
  1596.               {
  1597.                if (num_params > 2)
  1598.                  {
  1599.                   state = CURSOR_ERROR;
  1600.                   error_message = word[idx];
  1601.                   error_number = 1;
  1602.                   break;
  1603.                  }
  1604.                rc = cursor_up(escreen);
  1605.                time_to_leave = TRUE;
  1606.                break;
  1607.               }
  1608.             if (equal("down",word[idx],4))
  1609.               {
  1610.                if (num_params > 2)
  1611.                  {
  1612.                   state = CURSOR_ERROR;
  1613.                   error_message = word[idx];
  1614.                   error_number = 1;
  1615.                   break;
  1616.                  }
  1617.                rc = cursor_down(escreen);
  1618.                time_to_leave = TRUE;
  1619.                break;
  1620.               }
  1621.              /* validate numbers */
  1622.             if (strcmp(word[idx],"=") == 0)
  1623.                row = 0;
  1624.             else
  1625.               {
  1626.                if (!valid_positive_integer(word[idx]))
  1627.                  {
  1628.                   state = CURSOR_ERROR;
  1629.                   error_message = word[idx];
  1630.                   error_number = 4;
  1631.                   break;
  1632.                  }
  1633.                row = atoi(word[idx]);
  1634.               }
  1635.             idx++;
  1636.             if (strcmp(word[idx],"") == 0)
  1637.               {
  1638.                if (escreen)
  1639.                   col = 1;
  1640.                else
  1641.                   col = (CURRENT_VIEW->prefix&PREFIX_LOCATION_MASK) == PREFIX_LEFT ? PREFIX_WIDTH + 1 : 1;
  1642.               }
  1643.             else
  1644.               {
  1645.                if (strcmp(word[idx],"=") == 0)
  1646.                   col = 0;
  1647.                else
  1648.                  {
  1649.                   if (!valid_positive_integer(word[idx]))
  1650.                     {
  1651.                      state = CURSOR_ERROR;
  1652.                      error_message = word[idx];
  1653.                      error_number = 4;
  1654.                      break;
  1655.                     }
  1656.                   col = atoi(word[idx]);
  1657.                  }
  1658.               }
  1659.             rc = cursor_move(escreen,row,col);
  1660.             time_to_leave = TRUE;
  1661.             break;
  1662.        case CURSOR_KEDIT:
  1663.             if (equal("left",word[idx],4))
  1664.               {
  1665.                if (num_params > 2)
  1666.                  {
  1667.                   state = CURSOR_ERROR;
  1668.                   error_message = word[idx];
  1669.                   error_number = 1;
  1670.                   break;
  1671.                  }
  1672.                rc = cursor_left(TRUE,TRUE);
  1673.                time_to_leave = TRUE;
  1674.                break;
  1675.               }
  1676.             if (equal("right",word[idx],5))
  1677.               {
  1678.                if (num_params > 2)
  1679.                  {
  1680.                   state = CURSOR_ERROR;
  1681.                   error_message = word[idx];
  1682.                   error_number = 1;
  1683.                   break;
  1684.                  }
  1685.                rc = cursor_right(TRUE,TRUE);
  1686.                time_to_leave = TRUE;
  1687.                break;
  1688.               }
  1689.             state = CURSOR_ERROR;
  1690.             error_message = word[idx];
  1691.             error_number = 1;
  1692.             break;
  1693.        case CURSOR_ERROR:
  1694.             display_error(error_number,error_message,FALSE);
  1695.             rc = RC_INVALID_OPERAND;
  1696.             time_to_leave = TRUE;
  1697.             break;
  1698.       }
  1699.     if (time_to_leave)
  1700.        break;
  1701.    }
  1702. #ifdef TRACE
  1703.  trace_return();
  1704. #endif
  1705.  return(rc);
  1706. }
  1707. /*man-start*********************************************************************
  1708. COMMAND
  1709.      define - assign one or many commands to a key
  1710.  
  1711. SYNTAX
  1712.      DEFine key-name [command [args] [[#command [args]...]]]
  1713.  
  1714. DESCRIPTION
  1715.      The DEFINE command allows the user to assign one or many 
  1716.      commands and optional parameter(s) to a key. 
  1717.  
  1718.      Commands may be abbreviated.
  1719.  
  1720.      If multiple commands are assigned, then the LINEND setting
  1721.      must be ON and the LINEND character must match the character
  1722.      that delimits the commands at the time that the DEFINE command
  1723.      is executed. LINEND can be OFF at the time the key is pressed.
  1724.  
  1725.      With no arguments, any existing definition for that key is
  1726.      removed and the key reverts back to its default assignation (if
  1727.      it had any).
  1728.  
  1729.      key-names correspond to the key name shown with the SHOW command.
  1730.  
  1731. COMPATIBILITY
  1732.      XEDIT: N/A
  1733.      KEDIT: Minimal. No support for in-memory macro commands.
  1734.             KEDIT does not allow multiple commands except as KEXX
  1735.             macros.
  1736.  
  1737. SEE ALSO
  1738.      SHOW
  1739.  
  1740. STATUS
  1741.      Complete.
  1742. **man-end**********************************************************************/
  1743. #ifdef PROTO
  1744. short Define(CHARTYPE *params)
  1745. #else
  1746. short Define(params)
  1747. CHARTYPE *params;
  1748. #endif
  1749. /***********************************************************************/
  1750. {
  1751. /*--------------------------- local data ------------------------------*/
  1752. #define DEF_PARAMS  2
  1753.  CHARTYPE *word[DEF_PARAMS+1];
  1754.  unsigned short num_params=0;
  1755.  int key_value=0;
  1756.  short rc=RC_OK;
  1757. /*--------------------------- processing ------------------------------*/
  1758. #ifdef TRACE
  1759.  trace_function("comm1.c:   Define");
  1760. #endif
  1761.  num_params = param_split(params,word,DEF_PARAMS,WORD_DELIMS,TEMP_PARAM);
  1762.  if (num_params ==0)
  1763.    {
  1764.     display_error(3,(CHARTYPE *)"",FALSE);
  1765. #ifdef TRACE
  1766.     trace_return();
  1767. #endif
  1768.     return(RC_INVALID_OPERAND);
  1769.    }
  1770. /*---------------------------------------------------------------------*/
  1771. /* The first parameter is the key name mnemonic , the next is one or   */
  1772. /* more commands and/or parameters.                                    */
  1773. /* First check the mnemonic for decimal string value. ie begins with \ */
  1774. /*---------------------------------------------------------------------*/
  1775.  if (word[0][0] == '\\')
  1776.    {
  1777.     if ((key_value = atoi(word[0]+1)) == 0)
  1778.       {
  1779.        display_error(13,word[0],FALSE);
  1780.        rc = RC_INVALID_OPERAND;
  1781.       }
  1782.    }
  1783.  else
  1784.    {
  1785.     if ((key_value = find_key_value(word[0])) == (-1))
  1786.       {
  1787.        display_error(13,word[0],FALSE);
  1788.        rc = RC_INVALID_OPERAND;
  1789.        }
  1790.    }
  1791.  if (rc == RC_OK)
  1792.     rc = add_define(key_value,word[1]);
  1793. #ifdef TRACE
  1794.  trace_return();
  1795. #endif
  1796.  return(rc);
  1797. }
  1798. /*man-start*********************************************************************
  1799. COMMAND
  1800.      delete - delete lines from a file
  1801.  
  1802. SYNTAX
  1803.      DELete [target]
  1804.  
  1805. DESCRIPTION
  1806.      The DELETE command removes lines from the current file.
  1807.      The number of lines removed depends on the target specified.
  1808.      Lines are removed starting with the focus line.
  1809.  
  1810. COMPATIBILITY
  1811.      XEDIT: Compatible.
  1812.      KEDIT: Compatible.
  1813.  
  1814. DEFAULT
  1815.      1
  1816.  
  1817. SEE ALSO
  1818.      SOS DELLINE
  1819.  
  1820. STATUS
  1821.      Complete.
  1822. **man-end**********************************************************************/
  1823. #ifdef PROTO
  1824. short DeleteLine(CHARTYPE *params)
  1825. #else
  1826. short DeleteLine(params)
  1827. CHARTYPE *params;
  1828. #endif
  1829. /***********************************************************************/
  1830. {
  1831. /*-------------------------- external data ----------------------------*/
  1832.  extern VIEW_DETAILS *vd_mark;
  1833. /*--------------------------- local data ------------------------------*/
  1834.  LINETYPE start_line=0L,end_line=0L,dest_line=0L;
  1835.  short rc=RC_OK;
  1836.  CHARTYPE *args=NULL;
  1837.  TARGET target;
  1838.  short target_type=TARGET_NORMAL|TARGET_ALL|TARGET_BLOCK_CURRENT;
  1839.  bool lines_based_on_scope=FALSE;
  1840. /*--------------------------- processing ------------------------------*/
  1841. #ifdef TRACE
  1842.  trace_function("comm1.c:   DeleteLine");
  1843. #endif
  1844. /*---------------------------------------------------------------------*/
  1845. /* If no parameter is supplied, 1 is assumed.                          */
  1846. /*---------------------------------------------------------------------*/
  1847.  if (blank_field(params))
  1848.     args = (CHARTYPE *)"1";
  1849.  else
  1850.     args = params;
  1851.  initialise_target(&target);
  1852.  if ((rc = validate_target(args,&target,target_type,get_true_line(),TRUE,TRUE)) != RC_OK)
  1853.    {
  1854.     free_target(&target);
  1855. #ifdef TRACE
  1856.     trace_return();
  1857. #endif
  1858.     return(rc);
  1859.    }
  1860. /*---------------------------------------------------------------------*/
  1861. /* If the target is BLOCK and the marked block is a box block, call    */
  1862. /* box_operations(), otherwise delete specified lines.                 */
  1863. /*---------------------------------------------------------------------*/
  1864.  if (target.rt[0].target_type == TARGET_BLOCK_CURRENT)
  1865.    {
  1866. /*---------------------------------------------------------------------*/
  1867. /* For box blocks, call the appropriate function...                    */
  1868. /*---------------------------------------------------------------------*/
  1869.     if (MARK_VIEW->mark_type != M_LINE)
  1870.       {
  1871.        free_target(&target);
  1872.        box_operations(BOX_D,SOURCE_BLOCK_RESET,FALSE,' ');
  1873. #ifdef TRACE
  1874.        trace_return();
  1875. #endif
  1876.        return(RC_OK);
  1877.       }
  1878.     start_line = MARK_VIEW->mark_start_line;
  1879.     end_line = MARK_VIEW->mark_end_line;
  1880.     dest_line = MARK_VIEW->mark_start_line;
  1881.     lines_based_on_scope = FALSE;
  1882.    }
  1883.  else
  1884.    {
  1885.     start_line = target.true_line;
  1886.     if (target.num_lines < 0L)
  1887.       {
  1888.        end_line = (target.true_line + target.num_lines) + 1L;
  1889.        dest_line = end_line;
  1890.       }
  1891.     else
  1892.       {
  1893.        end_line = (target.true_line + target.num_lines) - 1L;
  1894.        dest_line = start_line;
  1895.       }
  1896.     lines_based_on_scope = TRUE;
  1897.    }
  1898.  free_target(&target);
  1899.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  1900.  if (target.num_lines != 0L)
  1901.     rc = rearrange_line_blocks(COMMAND_DELETE,SOURCE_COMMAND,start_line,
  1902.                             end_line,dest_line,1,CURRENT_VIEW,CURRENT_VIEW,lines_based_on_scope);
  1903.  CURRENT_VIEW->current_line = find_next_in_scope(NULL,CURRENT_VIEW->current_line,DIRECTION_FORWARD);
  1904.  CURRENT_VIEW->focus_line = find_next_in_scope(NULL,CURRENT_VIEW->focus_line,DIRECTION_FORWARD);
  1905.  if (rc == RC_OK)
  1906.    {
  1907.     if (CURRENT_BOF || CURRENT_TOF)
  1908.        rc = RC_TOF_EOF_REACHED;
  1909.    }
  1910. #ifdef TRACE
  1911.  trace_return();
  1912. #endif
  1913.  return(rc);
  1914. }
  1915. /*man-start*********************************************************************
  1916. COMMAND
  1917.      directory - list the specified directory as an editable file
  1918.  
  1919. SYNTAX
  1920.      DIRectory [filespec]
  1921.  
  1922. DESCRIPTION
  1923.      The DIRECTORY command displays all files matching the specified 
  1924.      file specification.
  1925.      When no parameter is supplied, all files in the current directory 
  1926.      are displayed subject to any SET DIRINCLUDE restrictions.
  1927.  
  1928. COMPATIBILITY
  1929.      XEDIT: N/A
  1930.      KEDIT: Compatible.
  1931.  
  1932. SEE ALSO
  1933.      LS, SET DIRINCLUDE
  1934.  
  1935. STATUS
  1936.      Complete.
  1937. **man-end**********************************************************************/
  1938. #ifdef PROTO
  1939. short Directory(CHARTYPE *params)
  1940. #else
  1941. short Directory(params)
  1942. CHARTYPE *params;
  1943. #endif
  1944. /***********************************************************************/
  1945. {
  1946. /*-------------------------- external data ----------------------------*/
  1947.  extern CHARTYPE *temp_cmd;
  1948.  extern CHARTYPE dir_filename[10];
  1949.  extern CHARTYPE dir_pathname[MAX_FILE_NAME+1];
  1950. /*--------------------------- local data ------------------------------*/
  1951. #define DIR_PARAMS  1
  1952.  CHARTYPE *word[DIR_PARAMS+1];
  1953.  unsigned short num_params=0;
  1954.  short rc=RC_OK;
  1955. /*--------------------------- processing ------------------------------*/
  1956. #ifdef TRACE
  1957.  trace_function("comm1.c:   Directory");
  1958. #endif
  1959. /*---------------------------------------------------------------------*/
  1960. /* Validate the parameters that have been supplied. The one and only   */
  1961. /* parameter should be the directory to display.                       */
  1962. /*---------------------------------------------------------------------*/
  1963.  num_params = param_split(params,word,DIR_PARAMS,WORD_DELIMS,TEMP_PARAM);
  1964.  if (num_params > 1)
  1965.    {
  1966.     display_error(1,(CHARTYPE *)word[1],FALSE);
  1967. #ifdef TRACE
  1968.     trace_return();
  1969. #endif
  1970.     return(RC_INVALID_OPERAND);
  1971.    }
  1972. /*---------------------------------------------------------------------*/
  1973. /* Validate that the supplied directory is valid.                      */
  1974. /*---------------------------------------------------------------------*/
  1975.  if ((rc = splitpath(strtrans(word[0],OSLASH,ISLASH))) != RC_OK)
  1976.    {
  1977.     display_error(10,(CHARTYPE *)word[0],FALSE);
  1978. #ifdef TRACE
  1979.     trace_return();
  1980. #endif
  1981.     return(rc);
  1982.    }
  1983.  if ((rc = read_directory()) != RC_OK)
  1984.    {
  1985.     display_error(10,(CHARTYPE *)word[0],FALSE);
  1986. #ifdef TRACE
  1987.     trace_return();
  1988. #endif
  1989.     return(rc);
  1990.    }
  1991.  strcpy(temp_cmd,dir_pathname);
  1992.  strcat(temp_cmd,dir_filename);
  1993.  Xedit(temp_cmd);
  1994. #ifdef TRACE
  1995.  trace_return();
  1996. #endif
  1997.  return(RC_OK);
  1998. }
  1999. /*man-start*********************************************************************
  2000. COMMAND
  2001.      dos - execute an operating system command
  2002.  
  2003. SYNTAX
  2004.      DOS [command]
  2005.  
  2006. DESCRIPTION
  2007.      The DOS command executes the supplied operating system command 
  2008.      or runs an interactive shell if no command is supplied.
  2009.  
  2010. COMPATIBILITY
  2011.      XEDIT: N/A
  2012.      KEDIT: Compatible.
  2013.  
  2014. SEE ALSO
  2015.      OS, !
  2016.  
  2017. STATUS
  2018.      Complete.
  2019. **man-end**********************************************************************/
  2020.  
  2021. /*man-start*********************************************************************
  2022. COMMAND
  2023.      dosnowait - execute an operating system command - no prompt
  2024.  
  2025. SYNTAX
  2026.      DOSNowait command
  2027.  
  2028. DESCRIPTION
  2029.      The DOSNOWAIT command executes the supplied operating system 
  2030.      command not waiting for the user to be prompted once the
  2031.      command has completed.
  2032.  
  2033. COMPATIBILITY
  2034.      XEDIT: N/A
  2035.      KEDIT: Compatible.
  2036.  
  2037. SEE ALSO
  2038.      OSNOWAIT
  2039.  
  2040. STATUS
  2041.      Complete.
  2042. **man-end**********************************************************************/
  2043.  
  2044. /*man-start*********************************************************************
  2045. COMMAND
  2046.      dosquiet - execute an operating system command quietly
  2047.  
  2048. SYNTAX
  2049.      DOSQuiet command
  2050.  
  2051. DESCRIPTION
  2052.      The OSQUIET command executes the supplied operating system command 
  2053.      as quietly as possible.
  2054.  
  2055. COMPATIBILITY
  2056.      XEDIT: N/A
  2057.      KEDIT: Compatible.
  2058.  
  2059. SEE ALSO
  2060.      OSQUIET
  2061.  
  2062. STATUS
  2063.      Complete.
  2064. **man-end**********************************************************************/
  2065.  
  2066. /*man-start*********************************************************************
  2067. COMMAND
  2068.      down - move forward in the file a number of lines
  2069.  
  2070. SYNTAX
  2071.      Down [relative_target]
  2072.  
  2073. DESCRIPTION
  2074.      The DOWN command moves the current line forwards the number of
  2075.      lines specified by the relative_target. This relative_target can 
  2076.      only be a positive integer or the character "*". 
  2077.  
  2078. COMPATIBILITY
  2079.      XEDIT: Compatible.
  2080.      KEDIT: Compatible.
  2081.  
  2082. DEFAULT
  2083.      1
  2084.  
  2085. SEE ALSO
  2086.      NEXT, UP
  2087.  
  2088. STATUS
  2089.      Complete.
  2090. **man-end**********************************************************************/
  2091.  
  2092. /*man-start*********************************************************************
  2093. COMMAND
  2094.      duplicate - duplicate lines
  2095.  
  2096. SYNTAX
  2097.      DUPlicate [n [target|BLOCK]]
  2098.  
  2099. DESCRIPTION
  2100.      The DUPLICATE command copies the number of lines extrapolated from
  2101.      target, n times.
  2102.  
  2103. COMPATIBILITY
  2104.      XEDIT: Equivalent of DUPLICAT command.
  2105.      KEDIT: Compatible.
  2106.  
  2107. STATUS
  2108.      Complete.
  2109. **man-end**********************************************************************/
  2110. #ifdef PROTO
  2111. short Duplicate(CHARTYPE *params)
  2112. #else
  2113. short Duplicate(params)
  2114. CHARTYPE *params;
  2115. #endif
  2116. /***********************************************************************/
  2117. {
  2118. /*------------------------- external data -----------------------------*/
  2119.  extern VIEW_DETAILS *vd_mark;
  2120. /*--------------------------- local data ------------------------------*/
  2121. #define DUP_PARAMS  2
  2122.  CHARTYPE *word[DUP_PARAMS+1];
  2123.  unsigned short num_params=0;
  2124.  short rc=RC_OK,num_occ=0;
  2125.  LINETYPE start_line=0L,end_line=0L,dest_line=0L;
  2126.  CHARTYPE command_source=0;
  2127.  TARGET target;
  2128.  short target_type=TARGET_NORMAL|TARGET_BLOCK_CURRENT|TARGET_ALL;
  2129.  bool lines_based_on_scope=FALSE;
  2130. /*--------------------------- processing ------------------------------*/
  2131. #ifdef TRACE
  2132.  trace_function("comm1.c:   Duplicate");
  2133. #endif
  2134.  num_params = param_split(params,word,DUP_PARAMS,WORD_DELIMS,TEMP_PARAM);
  2135. /*---------------------------------------------------------------------*/
  2136. /* If no parameters, default to 1 1                                    */
  2137. /*---------------------------------------------------------------------*/
  2138.  if (num_params == 0)
  2139.    {
  2140.     word[0] = (CHARTYPE *)"1";
  2141.     word[1] = (CHARTYPE *)"1";
  2142.    }
  2143. /*---------------------------------------------------------------------*/
  2144. /* If 1 parameter, default 2nd parameter to 1                          */
  2145. /*---------------------------------------------------------------------*/
  2146.  if (num_params == 1)
  2147.     word[1] = (CHARTYPE *)"1";
  2148. /*---------------------------------------------------------------------*/
  2149. /* If first parameter is not an integer, error.                        */
  2150. /*---------------------------------------------------------------------*/
  2151.  if (!valid_integer(word[0]))
  2152.    {
  2153.     display_error(4,word[0],FALSE);
  2154. #ifdef TRACE
  2155.     trace_return();
  2156. #endif
  2157.     return(RC_INVALID_OPERAND);
  2158.    }
  2159.  num_occ = atoi(word[0]);
  2160. /*---------------------------------------------------------------------*/
  2161. /* Validate second parameter is a valid target...                      */
  2162. /*---------------------------------------------------------------------*/
  2163.  initialise_target(&target);
  2164.  if ((rc = validate_target(word[1],&target,target_type,get_true_line(),TRUE,TRUE)) != RC_OK)
  2165.    {
  2166.     free_target(&target);
  2167. #ifdef TRACE
  2168.     trace_return();
  2169. #endif
  2170.     return(rc);
  2171.    }
  2172. /*---------------------------------------------------------------------*/
  2173. /* Duplicate lines depending on target type...                         */
  2174. /*---------------------------------------------------------------------*/
  2175.  switch(target.rt[0].target_type)
  2176.    {
  2177.     case TARGET_BLOCK_CURRENT:
  2178. /*---------------------------------------------------------------------*/
  2179. /* This function not valid for box  blocks.                            */
  2180. /*---------------------------------------------------------------------*/
  2181.          if (MARK_VIEW->mark_type == M_BOX)
  2182.            {
  2183.             display_error(48,(CHARTYPE *)"",FALSE);
  2184. #ifdef TRACE
  2185.             trace_return();
  2186. #endif
  2187.             return(RC_INVALID_ENVIRON);
  2188.            }
  2189.          command_source = SOURCE_BLOCK;
  2190.          start_line = MARK_VIEW->mark_start_line;
  2191.          end_line = dest_line = MARK_VIEW->mark_end_line;
  2192.          lines_based_on_scope = FALSE;
  2193.          break;
  2194.     default:
  2195.          command_source = SOURCE_COMMAND;
  2196.          start_line = target.true_line;
  2197.          end_line = dest_line = (target.true_line + target.num_lines) - 1L;
  2198.          lines_based_on_scope = TRUE;
  2199.          break;
  2200.    }
  2201.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  2202.  rc = rearrange_line_blocks(COMMAND_DUPLICATE,command_source,
  2203.                             start_line,end_line,dest_line,num_occ,
  2204.                             CURRENT_VIEW,CURRENT_VIEW,lines_based_on_scope);
  2205.  free_target(&target);
  2206. #ifdef TRACE
  2207.  trace_return();
  2208. #endif
  2209.  return(rc);
  2210. }
  2211.